package meiyunting.shiwuzhaoling.service.impl;

import meiyunting.shiwuzhaoling.dto.UserRegistrationDTO;
import meiyunting.shiwuzhaoling.model.User;
import meiyunting.shiwuzhaoling.model.UserRole;
import meiyunting.shiwuzhaoling.repository.UserRepository;
import meiyunting.shiwuzhaoling.service.UserService;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import meiyunting.shiwuzhaoling.model.Item;
import meiyunting.shiwuzhaoling.model.Claim;
import meiyunting.shiwuzhaoling.repository.ItemRepository;
import meiyunting.shiwuzhaoling.repository.ClaimRepository;
import meiyunting.shiwuzhaoling.model.ItemStatus;
import meiyunting.shiwuzhaoling.model.ItemType;

@Service
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;
    private final ItemRepository itemRepository;
    private final ClaimRepository claimRepository;

    @Autowired
    public UserServiceImpl(UserRepository userRepository, PasswordEncoder passwordEncoder, 
                          ItemRepository itemRepository, ClaimRepository claimRepository) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
        this.itemRepository = itemRepository;
        this.claimRepository = claimRepository;
    }

    @Override
    public User registerUser(UserRegistrationDTO registrationDTO) {
        try {
            // 记录原始用户名，以便调试
            String originalUsername = registrationDTO.getUsername();
            System.out.println("尝试注册用户，原始用户名: " + originalUsername);
            
            if (userRepository.existsByUsername(originalUsername)) {
                throw new RuntimeException("用户名已存在");
            }
            if (userRepository.existsByEmail(registrationDTO.getEmail())) {
                throw new RuntimeException("邮箱已被注册");
            }
            
            // 验证密码和确认密码是否匹配
            if (!registrationDTO.getPassword().equals(registrationDTO.getConfirmPassword())) {
                throw new RuntimeException("两次输入的密码不一致");
            }

            User user = new User();
            user.setUsername(originalUsername);
            String encodedPassword = passwordEncoder.encode(registrationDTO.getPassword());
            user.setPassword(encodedPassword);
            user.setEmail(registrationDTO.getEmail());
            user.setRole(UserRole.USER); // 默认为普通用户角色
            user.setCreatedAt(LocalDateTime.now());
            user.setUpdatedAt(LocalDateTime.now());

            System.out.println("准备保存用户: " + user.getUsername() + ", 加密后密码: " + encodedPassword);
            
            User savedUser = userRepository.save(user);
            System.out.println("用户保存成功，保存后的用户名: " + savedUser.getUsername() + ", ID: " + savedUser.getId());
            
            return savedUser;
        } catch (Exception e) {
            System.err.println("注册用户时发生异常: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("注册失败: " + e.getMessage(), e);
        }
    }

    @Override
    public User findByUsername(String username) {
        Optional<User> userOptional = userRepository.findByUsername(username);
        if (!userOptional.isPresent()) {
            System.out.println("用户不存在: " + username);
            throw new RuntimeException("用户不存在: " + username);
        }
        System.out.println("找到用户: " + username + ", 密码哈希: " + userOptional.get().getPassword());
        return userOptional.get();
    }

    @Override
    public boolean validateUser(String username, String password) {
        return userRepository.findByUsername(username)
                .map(user -> {
                    boolean matches = passwordEncoder.matches(password, user.getPassword());
                    System.out.println("验证用户: " + username + ", 输入密码: " + password + ", 存储密码: " + user.getPassword() + ", 匹配结果: " + matches);
                    if (!matches) {
                        System.out.println("密码不匹配: " + username);
                    }
                    return matches;
                })
                .orElse(false);
    }

    @Override
    public User getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            return null;
        }
        return findByUsername(authentication.getName());
    }
    
    // 管理员功能实现
    @Override
    public List<User> findAllUsers() {
        return userRepository.findAll();
    }
    
    @Override
    public User findById(Long id) {
        return userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
    }
    
    @Override
    public void updateUserRole(Long id, UserRole role) {
        User user = findById(id);
        user.setRole(role);
        userRepository.save(user);
    }
    
    @Override
    @Transactional
    public void deleteUser(Long id) {
        try {
            User user = findById(id);
            
            // 1. 找出该用户发布的所有物品
            List<Item> userItems = itemRepository.findByUser(user);
            System.out.println("用户ID:" + id + " 关联的物品数量: " + userItems.size());
            
            // 2. 对于每个物品，先删除与其关联的认领记录
            for (Item item : userItems) {
                List<Claim> claims = claimRepository.findByItem(item);
                System.out.println("物品ID:" + item.getId() + " 关联的认领记录数量: " + claims.size());
                claimRepository.deleteAll(claims);
            }
            
            // 3. 删除用户发布的所有物品
            itemRepository.deleteAll(userItems);
            
            // 4. 删除该用户的所有认领记录
            List<Claim> userClaims = claimRepository.findByClaimerId(id);
            System.out.println("用户ID:" + id + " 作为认领者的记录数量: " + userClaims.size());
            claimRepository.deleteAll(userClaims);
            
            // 5. 将该用户认领的物品的认领状态清除
            List<Item> claimedItems = itemRepository.findByClaimedBy(user);
            for (Item item : claimedItems) {
                item.setClaimedBy(null);
                item.setClaimedAt(null);
                // 如果物品状态为完成，则改为对应的原始状态
                if (item.getStatus() == ItemStatus.COMPLETED) {
                    // 根据物品类型判断其原始状态（这里逻辑可能需要根据实际业务调整）
                    item.setStatus(ItemStatus.FOUND);
                }
                itemRepository.save(item);
            }
            
            // 6. 最后删除用户本身
            userRepository.deleteById(id);
            System.out.println("用户ID:" + id + " 已成功删除");
        } catch (Exception e) {
            System.err.println("删除用户失败: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("删除用户失败: " + e.getMessage(), e);
        }
    }

    @Override
    public User updateUser(Long id, String username, String email, UserRole role) {
        User user = findById(id);
        
        // 检查用户名是否已被其他用户使用
        if (!user.getUsername().equals(username) && userRepository.existsByUsername(username)) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 检查邮箱是否已被其他用户使用
        if (!user.getEmail().equals(email) && userRepository.existsByEmail(email)) {
            throw new RuntimeException("邮箱已被注册");
        }
        
        user.setUsername(username);
        user.setEmail(email);
        user.setRole(role);
        user.setUpdatedAt(LocalDateTime.now());
        
        return userRepository.save(user);
    }
} 